;伪指令
; 0柱面0磁道1扇区
;org : 定义一个锚点
[ORG  0x7c00]
; section定义一个段
[SECTION .data]
BOOT_MAIN_ADDR equ 0x500

[SECTION .text]
[BITS 16]
;nasm 汇编
global boot_start
boot_start:
    ;设置文本模式，清空屏幕
    mov ax, 3
    int 0x10

   mov edi, BOOT_MAIN_ADDR
   mov ecx, 1 ;从磁盘哪个扇区开始读
   mov bl,  2 ; 读取的扇区数量
   call read_hd

   mov si,jmp_to_setup
   call print

   jmp BOOT_MAIN_ADDR
read_hd:
   ;0x1f2 8bit 指定读取或写入的扇区数
   mov dx, 0x1f2
   mov al, bl
   out dx, al

   ;0x1f3 8bit iba地址的低八位 0-7
   inc dx
   mov al, cl
   out dx,al

   ;0x1f4 8bit iba地址的中八位 8-15
   inc dx
   mov al, ch
   out dx,al

   ;0x1f5 8bit iba地址高八位 16-23
   inc dx
   shr ecx,16
   mov al, cl
   out dx, al

   ;0x1f6 8bit
   ;0-3 位 iba地址的24-27
   ;4 0 主盘 1 从盘
   ;5 / 7 位 固定1
   ;6 0:CHS 1:LAB
   inc dx
   shr ecx,8
   and cl, 0b1111
   mov al,0b1110_0000 ;LBA
   or al,cl
   out dx, al

   ;0x1f7 8bit 命令或状态端口
   inc dx
   mov al,0x20
   out dx,al
   ;验证状态
   ;3 0 表示磁盘未准备好与主机交换数据 1表示准备好了
   ;7 0 表示磁盘不忙 1表示磁盘繁忙
   ;8 0表示前一条指令正常执行 1表示出错
    mov cl, bl
.start_read:
    push cx ;保存loop次数

    call .wait_hd_prepare
    call read_hd_data

    pop cx ;恢复次数
    loop .start_read
.return:
    ret

;等待 不繁忙且准备好 7：0 3：1 0：0
.wait_hd_prepare:
    mov dx, 0x1f7


.check:
    in al,dx
    and al,0b1000_1000
    cmp al,0b0000_1000
    jnz .check

    ret
;读硬盘 一次2字节 256次一扇区
read_hd_data:
    mov dx,0x1f0
    mov cx,256


.read_word:
    in ax,dx
    mov [edi],ax
    add edi,2
    loop .read_word

    ret
    ;mov si msg
    ;call print
print:
    mov ah, 0x0e
    mov bh, 0
    mov bl, 0x01
.loop:
    mov al, [si]
    cmp al, 0
    jz .done
    int 0x10

    inc si
    jmp .loop
.done:
    ret


jmp_to_setup:
    db "jmp to boot" ,10,13, 0


;末尾填充 对齐填充 $$:所在段的起始位置
times 510 - ($ - $$) db 0
db 0x55, 0xaa